package algorthm.systemTraning.linkedList;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * @className: NumberComparator
 * @Description:
 * @Author: wangyifei
 * @Date: 2022/8/30 21:28
 */
public class NumberComparator {
    public static SingleNode fakeSingleLinkedList(int range , int size){
        Random random = new Random();
        int r = 0 ;
        SingleNode head = null ;
        SingleNode cur = null ;
        SingleNode pre = null ;
        size = random.nextInt(size) + 1;
        for(int i = 0 ; i < size ; i++){
            r = random.nextInt(range);
            cur = new SingleNode();
            cur.setValue(r);
            if(head == null){
                head = cur ;
            }
            if(pre != null){
                pre.setNext(cur);
            }
            pre = cur ;
        }
        return head ;
    }
    public static DoubleNode fakeDoubleLinkedList(int range , int size){
        Random random = new Random();
        int r = 0 ;
        DoubleNode head = null ;
        DoubleNode cur = null ;
        DoubleNode pre = null ;
        size = random.nextInt(size) + 1;
        for(int i = 0 ; i < size ; i++){
            r = random.nextInt(range);
            cur = new DoubleNode();
            cur.setValue(r);
            cur.setPre(pre);
            if(head == null){
                head = cur ;
            }
            if(pre != null){
                pre.setNext(cur);
            }
            pre = cur ;
        }
        return head ;
    }
    public static DoubleNode reverseDoubleLinkedList(DoubleNode head){
         DoubleNode pre = null ;
         DoubleNode next = null ;
         DoubleNode cur = head ;
         List<Integer> l = new ArrayList<>();
         while(head != null){
             l.add(head.getValue());
             head = head.getNext();
         }
         for(int i = l.size() - 1 ; i >= 0 ; i--){

             cur = new DoubleNode();
             cur.setValue(l.get(i));
             cur.setPre(pre);
             if(head == null){
                 head = cur ;
             }
             if(pre != null){
                 pre.setNext(cur);
             }
             pre = cur ;

         }
         return head ;
    }
    public static SingleNode reverseSingleLinkedList(SingleNode head){
        List<Integer> l = new ArrayList<>();
        SingleNode ans = null ;
        SingleNode cur = null ;
        SingleNode pre = null ;
        int r = 0 ;
        while(head != null){
            l.add(head.getValue());
            head = head.getNext();
        }
        for(int i = l.size() - 1 ; i >= 0 ; i--){
            r = l.get(i);
            cur = new SingleNode();
            cur.setValue(r);
            if(ans == null){
                ans = cur ;
            }
            if(pre == null){
                ans.setNext(cur);
            }else {
                pre.setNext(cur);
            }
            pre = cur ;
        }
        return ans ;
    }
    public static SingleNode copySingleLinkedList(SingleNode head){
        SingleNode pre = null ;
        SingleNode next = null ;
        SingleNode h = null;
        System.out.println();
        while(head != null){
            next = new SingleNode();
            next.setValue(head.getValue());
            if(pre != null){
                pre.setNext(next);
            }
            if(h == null){
                h = next ;
            }
            pre = next ;
            head = head.getNext();
        }
        return h ;
    }
    public static DoubleNode copyDoubleLinkedList(DoubleNode head){

        DoubleNode cur = head ;
        DoubleNode pre = null ;
        DoubleNode n = null ;
        DoubleNode newHead = null;
        int i =  0 ;
        while(cur != null){
            i++ ;
            n = new DoubleNode();
            n.setValue(cur.getValue());
            if(pre != null){
                pre.setNext(n);
            }
            n.setPre(pre);
            pre = n ;
            if(newHead == null){
                newHead = n ;
            }
            cur = cur.getNext();
        }
        return newHead ;
    }
    public static void compareDouble(int range , int size , int compareTime){
        DoubleNode head = null ;
        DoubleNode node = null ;
        DoubleNode node1 = null ;
        int j = 0 ;
        for(int i = 0 ; i < compareTime ; i++){
            head = fakeDoubleLinkedList(range , size);
            DoubleNode node2 = copyDoubleLinkedList(head);
            node = reverseDoubleLinkedList(head);
            node1 = ReverseLinkedList.reverseDoubleNodeLinkedList(node2);
            j = 0 ;
            while(node != null && node1 != null){
               if(node.getValue() != node1.getValue()) {
                   System.out.println("not equal 1");
                   break;
               }
               node = node.getNext();
               node1 = node1.getNext();
               j++;
            }
            if(j != size){
                System.out.println("not equal");
            }
        }
    }
    public static void compareSingle(int range , int size , int compareTime){
        SingleNode singleNode = null ;
        SingleNode node1 = null ;
        SingleNode node2 = null ;
        StringBuilder sb1 = new StringBuilder();
        StringBuilder sb2 = new StringBuilder();
        int j = 0 ;

        for(int i = 0 ; i < compareTime ; i++){
            singleNode = fakeSingleLinkedList(range, size);
            node1 = reverseSingleLinkedList(singleNode);
            node2 = ReverseLinkedList.reverseSingleNode(singleNode);
            j = 0 ;
            while(node1 != null && node2 != null){
                if(node1.getValue() != node1.getValue()){
                    System.out.println("not equel occur");
                    continue;
                }
                sb1.append(node1.getValue());
                sb2.append(node2.getValue());
                node1 = node1.getNext();
                node2 = node2.getNext();
                j++;
            }
            if(j != size){
                System.out.println("not equal occur");
            }
            if (!sb1.toString().equals(sb2.toString())) {
                System.out.println("not equal occur");
            }
            if(node1 != null || node2 != null){
                System.out.println("not equel occur 1");
            }
        }
    }
    public static void forNodes(SingleNode head){
        SingleNode h = head ;
        while(h != null){
            System.out.print(h.getValue() + ",");
            h = h.getNext();
        }
    }
    public static void forNodes(DoubleNode head){
        DoubleNode h = head ;
        while(h != null){
            System.out.print(h.getValue() + ",");
            h = h.getNext();
        }
    }
    public static void main(String[] args) {
//        SingleNode singleNode = fakeSingleLinkedList(100, 50);
//        int idx = 1 ;
//        while(singleNode != null){
//            System.out.println(idx++ + ":" + singleNode.getValue());
//            singleNode = singleNode.getNext();''
//        }
        compareDouble(200 , 80 , 1000);
//        DoubleNode node = fakeDoubleLinkedList(100, 12);
//        forNodes(node);
//        System.out.println();
//        DoubleNode node1 = reverseDoubleLinkedList(node);
//        forNodes(node1);
        DoubleNode h = null ;
        m(h);
        System.out.println(h);
    }
    public static DoubleNode m(DoubleNode head){
        head = new DoubleNode();
        return head;
    }
}
